package com.yiyw.herostory.pipeline.Inbound;

import com.google.protobuf.GeneratedMessageV3;
import com.yiyw.herostory.factory.CmdHandlerFactory;
import com.yiyw.herostory.handler.ICmdHandler;
import com.yiyw.herostory.manage.ChannelGroupManage;
import com.yiyw.herostory.manage.UserManage;
import com.yiyw.herostory.proto.GameMsgProtocol;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @Author yiyw
 * @Description 消息处理器
 * @Date 2022/8/13 17:26
 **/
@Slf4j
public class GameMasHandler extends ChannelInboundHandlerAdapter {

    ExecutorService executors = Executors.newSingleThreadExecutor((r) -> {
        Thread newThread = new Thread(r);
        newThread.setName("MainThreadProcessor");
        return newThread;
    });


    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        super.channelActive(ctx);
        ChannelGroupManage.addChannel(ctx.channel());
    }

    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
        super.handlerRemoved(ctx);
        // 将 channel 移除
        ChannelGroupManage.removeChannel(ctx.channel());
        GameMsgProtocol.UserQuitResult.Builder result = GameMsgProtocol.UserQuitResult.newBuilder();
        // 获取用户 ID
        Integer userId = ChannelGroupManage.getUserIdByChannel(ctx.channel());
        result.setQuitUserId(userId);
        // 移除用户在线列表
        UserManage.removeUser(userId);
        // 给所有用户发送消息
        ChannelGroupManage.writeAndFlush(result.build());
    }


    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) {
        if (msg instanceof GeneratedMessageV3) {
            log.info("接收到客户端的消息, \n消息类型: {}, 消息内容: {}", msg.getClass().toString(), msg);
            ICmdHandler handler = CmdHandlerFactory.getHandler(msg);
            if (handler != null) {
                // 单线程执行任务
                executors.submit(() -> {
                    try {
                        handler.handler(ctx, (GeneratedMessageV3) msg);
                    }catch (Exception e) {
                        log.error(e.getMessage(), e);
                    }
                });
            }
        }
    }
}
